# -*- coding:utf-8 -*-
import re
import numpy as np
from metlib.datetime import T, TD
from metlib.kits import *
from filecache.filecache_manager import *
from datakeeper.utils import *
import matplotlib
matplotlib.use('Agg')
from matplotlib.cm import *
from collections import OrderedDict

# c9a_transporter = FileTransporter(remote_location='s3://windres-datasets', retry=2, retry_interval=1)
# c9a_fc_manager = FileCacheManager(bucket='c9a_raw',
#                                     transporter=c9a_transporter)
# c9a2d_fc_manager = FileCacheManager(bucket='c9a2d_raw',
#                                   transporter=c9a_transporter)
# c9a_kmz_manager = FileCacheManager('c9a_kmz_img_tmp')


# TODO: use generator instead.  Depreciated?
fgwrf_domain_resolution_d = {
    "1": "27km",
    "2": "9km",
    "3": "9km",
    "4": "9km",
    "5": "9km",
    "6": "9km",
    "7": "9km",
    1: "27km",
    2: "9km",
    3: "9km",
    4: "9km",
    5: "9km",
    6: "9km",
    7: "9km",
}

# 单位的字典
fgwrf_units_d = {
    "wspd": u"m/s",
    "wdir": u"°",
    "wspd10m": u"m/s",
    "wdir10m": u"°",
    "ust": u"m/s",
    "wpd": u"W/m²",
    "t2m": u"°C",
    "t": u"°C",
    "td": u"°C",
    "psfc": u"hPa",
    "p": u"hPa",
    "rhoair": u"kg/m³",
    "rh": u"%",
    "rh2m": u"%",
    "q2m": u"g/kg",
    "tdew2m": u"°C",
    "ts": u"°C",
    "tskin": u"°C",
    "slp": u"hPa",
    "rain": u"mm",
    "snow": u"mm",
    "swdown": u"W/m²",
    "glw": u"W/m²",
    "ghi": u"W/m²",
    "dni": u"W/m²",
    "ddir": u"W/m²",
    "ddif": u"W/m²",
    "summary": u"",
    "windrose": u"‰",
    "wpdrose": u"kWh/m²",
    "dist": u"%",
    "eqhour": u"h",
    "temp": u"°C",
    "dew": u"°C",
    "pres": u"hPa",
    "dir": u"°",
    "height": u"km",
}
fgwrf_py_units_d = fgwrf_units_d.copy()
fgwrf_py_units_d.update({
    "swdown": u"kWh/m²",
    "glw": u"kWh/m²",
    "ghi": u"kWh/m²",
    "dni": u"kWh/m²",
    "ddir": u"kWh/m²",
    "ddif": u"kWh/m²",
})
fgwrf_pm_units_d = fgwrf_units_d.copy()
fgwrf_pm_units_d.update({
    "swdown": u"kWh/m²",
    "glw": u"kWh/m²",
    "ghi": u"kWh/m²",
    "dni": u"kWh/m²",
    "ddir": u"kWh/m²",
    "ddif": u"kWh/m²",
})
fgwrf_pd_units_d = fgwrf_units_d.copy()
fgwrf_pt_units_d = fgwrf_units_d.copy()

fgwrf_normal_varnames = ['wspd', 'wpd', 'psfc', 'td', 'rhoair', 'rh']
fgwrf_mean_varnames = ['wspd', 'wpd', 'psfc', 'td', 'rhoair', 'rh']
fgwrf_sfc_varnames = ['rain', 'snow', 'ts', 'slp', 'swdown', 'glw']
fgwrf_pt_varnames = ['wspd', 'wdir', 'wpd', 'psfc', 'td', 'rhoair', 'rh']
fgwrf_py_varnames = ['summary', 'eqhour', 'windrose', 'wpdrose', 'dist']
fgwrf_pm_varnames = fgwrf_mean_varnames
fgwrf_pd_varnames = fgwrf_mean_varnames
fgwrf_ry_varnames = ['wspd', 'wpd', 'psfc', 'td', 'rhoair', 'rh']
fgwrf_ry_sfc_varnames = fgwrf_sfc_varnames

fgwrf_combine_varname_d = {
    "t": OrderedDict([("sfc", "tskin")]),
    "td": OrderedDict([("sfc", "ts")]),
}

fgwrf_turbine_models = ['GW70', 'GW77', 'GW93', 'GW115', 'EN110', 'MY104', 'H111', 'G97', 'UP105']


# Depreciated?
fgwrf_zh_dataset_d = {
    'china_9km_anl': u'全国9km再分析(C9A)'
}

# 中文subset名字典
fgwrf_zh_subset_d = {
    'PT': u'时间序列',
    'PY': u'年统计值',
    'PM': u'月统计值',
    'PD': u'日变化',
    'RY': u'年统计值'
}

# 中文变量名字典
fgwrf_zh_varname_d = {
    "wspd": u"风速",
    "wdir": u"风向",
    "wspd10m": u"10米风速",
    "wdir10m": u"10米风向",
    "ust": u"摩擦速度",
    "wpd": u"风功率密度",
    "td": u"温度",
    "t": u"温度",
    "t2m": u"2米温度",
    "psfc": u"气压",
    "p": u"气压",
    "rhoair": u"空气密度",
    "rh": u"相对湿度",
    "rh2m": u"2米相对湿度",
    "q2m": u"2米比湿",
    "tdew2m": u"2米露点温度",
    "summary": u"汇总统计",
    "sfc_summary": u"地面汇总",
    "windrose": u"风玫瑰",
    "wpdrose": u"风功率玫瑰",
    "dist": u"风速分布",
    "eqhour": u"等效小时数",
    "rain": u"降雨",
    "snow": u"降雪",
    "ts": u"地表温度",
    "tskin": u"地表温度",
    "slp": u"海平面气压",
    "swdown": u"向下短波辐射",
    "glw": u"向下长波辐射",
    "ghi": u"向下短波辐射",
    "dni": u"法向直接短波辐射",
    "ddir": u"直接短波辐射",
    "ddif": u"散射短波辐射",
    'temp': u"温度",
    "dew": u"露点温度",
    "pres": u"气压",
    "dir": u"风向",
    "wspd": u"风速",
    "height": u"高度",
}

# 坐标中文名字典
fgwrf_coord_name_d = {
    "time": u"时间",
    "level": u"高度层",
    "year": u"年",
    "resolution": u"分辨率",
    "version": u"版本",
}

#
fgwrf_suburi_product_type_d = {
    'PT': 'ModelPointSeries',
    'PY': 'ModelPointYearlyStat',
    'PM': 'ModelPointMonthlyStat',
    'PD': 'ModelPointDiurnalStat',
    # TODO: more
}

# 子集完整名字典
fgwrf_subset_fullname_d = {
    'PT': 'PointTimeseries',
    'PY': 'PointYearlyStat',
    'PM': 'PointMonthlyStat',
    'PD': 'PointDiurnalStat',
}

# 数值有效范围
fgwrf_value_limit_d = {
    "wspd": (0.0, 999.0, np.nan),
    "wdir": (0.0, 360.0, np.nan),
    "wpd": (0.0, 99999.0, np.nan),
    "td": (-100.0, 100.0, np.nan),
    "psfc": (0.0, 1500.0, np.nan),
    "rhoair": (0.0, 1.5, np.nan),
    "rh": (0.0, 500.0, np.nan),
}

# 建议绘图数值范围
fgwrf_suggest_range_d = {
    "wspd": (3.0, 10.0),
    "wdir": (0.0, 360.0),
    "wspd10m": (3.0, 10.0),
    "wdir10m": (0.0, 360.0),
    "ust": (None, None),  # TODO
    "wpd": (0.0, 1000.0),
    "td": (-10.0, 30.0),
    "t": (-10.0, 30.0),
    "t2m": (-10.0, 30.0),
    "psfc": (None, None),
    "p": (None, None),
    "rhoair": (0.6, 1.3),
    "rh": (20.0, 100.0),
    "rh2m": (20.0, 100.0),
    "q2m": (None, None),  # TODO,
    "rain": (0, 4000),
    "snow": (0, 400),
    "swdown": (1000, 2500),
    "glw": (1500, 3800),
    "ghi": (1000, 2500),
    "dni": (1400, 3300),
    "ddir": (1000, 2500),
    "ddif": (1000, 2500),  # TODO
    "slp": (960, 1050),
    "ts": (-10.0, 30.0),
    "tskin": (-10.0, 30.0),
}
fgwrf_pt_suggest_range_d = fgwrf_suggest_range_d.copy()
fgwrf_pt_suggest_range_d.update({
    "rain": (0, 5),
    "snow": (0, 0.5),
    "swdown": (0, 1200),
    "glw": (100, 400),
    "ghi": (0, 1200),
    "dni": (0, 1200),
    "ddir": (0, 1200),
    "ddif": (0, 1200),
})
fgwrf_py_suggest_range_d = fgwrf_suggest_range_d.copy()
fgwrf_py_suggest_range_d.update({
    "slp": (1010, 1025)
})
fgwrf_pm_suggest_range_d = fgwrf_suggest_range_d.copy()
fgwrf_pm_suggest_range_d.update({
    "rain": (0, 500),
    "snow": (0, 200),
    "swdown": (100, 280),
    "glw": (100, 350),
    "ghi": (100, 280),
    "dni": (100, 280),
    "ddir": (100, 280),
    "ddif": (100, 280),
    "slp": (980, 1030)
})
fgwrf_pd_suggest_range_d = fgwrf_suggest_range_d.copy()
fgwrf_pd_suggest_range_d.update({
    "rain": (0, 500),
    "snow": (0, 15),
    "swdown": (0, 1200),
    "glw": (100, 400),
    "ghi": (0, 1200),
    "dni": (0, 1200),
    "ddir": (0, 1200),
    "ddif": (0, 1200),
    "slp": (1005, 1025)
})

#
fgwrf_cmap_d = {
    'jet': 'jet',
    'YlGnBu': 'YlGnBu',
    'rainbow': 'gist_rainbow_r',
    'Spectral_r':' Spectral_r',
    'Spectral': 'Spectral'
}

# 推荐的色表
fgwrf_suggest_cmap_d = {
    'td': 'temperature',
    't': 'temperature',
    't2m': 'temperature',
    'ts': 'temperature',
    'tskin': 'temperature',
    'psfc': 'pressure',
    'p': 'pressure',
    'swdown': 'solar',
    'glw': 'solar',
    'ghi': 'solar',
    'dni': 'solar',
    'ddir': 'solar',
    'ddif': 'solar',
    'slp': 'terrain2_r',
    'rh': 'rain',
    'rh2m': 'rain',
    'q2m': 'rain',
    'rain': 'rain',
    'snow': 'rain'
}


# 解析uri
def parse_fgwrf_uri(uri):
    result = {}
    m = re.match(r'(?P<dataset>[^/]+)/(?P<subset>[^/]+)/(?P<varname>[^/]+)/(?P<time>[^-+Z/]+)(Z?)(?P<timezone>[-+0-9]*)/(?P<level>[^/]+)/(?P<grid>[^/]+)$', uri)
    if not m:
        raise ValueError('%s is not a proper fgwrf uri' % uri)
    for field in ['dataset', 'subset', 'varname', 'time', 'level', 'grid']:
        result[field] = m.group(field)

    # grid -> domain, jy_ix
    domain, jy_ix = m.group('grid').split('_', 1)
    result['domain'] = domain
    result['jy_ix'] = jy_ix

    time_str = m.group('time')
    timezone_str = m.group('timezone')
    try:
        timezone = int(timezone_str)
    except ValueError:
        timezone = 0
    toffset = TD('%sh' % timezone)

    if ',' in time_str:
        times = time_str.split(',')
        result['times'] = times
        result['timetype'] = 'year_list'
    elif ':' in time_str:
        begdt, enddt, tdelta = parse_slice_str(time_str, default_step='1h')
        begdt = T(begdt)
        enddt = T(enddt)
        result['timetype'] = 'dtrange'
        result['begdt'] = begdt
        result['enddt'] = enddt
        result['tdelta'] = tdelta
        result['std_begdt'] = begdt - toffset
        result['std_enddt'] = enddt - toffset
    elif len(time_str) == 4:  # year
        begdt = T(time_str+'0101')
        enddt = begdt + TD('1Y')
        tdelta = '1h'
        result['year'] = time_str
        result['timetype'] = 'year'
        result['timetype'] = 'dtrange'
        result['begdt'] = begdt
        result['enddt'] = enddt
        result['tdelta'] = tdelta
        result['std_begdt'] = begdt - toffset
        result['std_enddt'] = enddt - toffset
    else:
        raise ValueError('%s is not a proper fgwrf uri' % uri)
    result['timezone'] = timezone

    return result

def fgwrf_minimize_uri(uri):
    return uri
    # if isinstance(uri, dict):
    #     uri_info = uri
    # else:
    #     uri_info = parse_fgwrf_uri(uri)
    # if uri_info['subset'] in ('PY', 'PM', 'PD'):
    #     min_uri = '%(dataset)s/%(subset)s/*/%(year)s/%(domain)s/*/%(jy_ix)s' % uri_info
    # elif uri_info['subset'] == 'PT':
    #     min_uri = '%(dataset)s/%(subset)s/%(varname)s/%(std_begdt)s:%(std_enddt)s:%(tdelta)s/%(domain)s/%(level)s/%(jy_ix)s' % uri_info
    # elif uri_info['subset'] == 'RY':
    #     min_uri = '%(dataset)s/%(subset)s/%(varname)s/%(year)s/%(domain)s/%(level)s/%(jy_ix)s' % uri_info
    # return min_uri

# uri到存储路径转换
# def fgwrf_uri2path(uri):
#     m = re.match(r'(?P<dataset>[^/]+)/(?P<subset>[^/]+)/(?P<varname>[^/]+)/(?P<time>[^/]+)/(?P<domain>[^/]+)/(?P<level>[^/]+)/(?P<jy_ix>[^/]+)$', uri)
#     if not m:
#         raise ValueError('%s is not a proper fgwrf uri' % uri)
#     result = re.sub(r'\*', 'ALL', uri)
#     # result = re.sub(r':', '++', result)
#     return result

def fgwrf_uri_old2new(uri):
    parts = uri.split('/')
    assert(len(parts) == 7)
    return '%s/%s/%s/%s/%s/%s_%s' % (parts[0], parts[1], parts[2], parts[3], parts[5], parts[4], parts[6])
